import {useState} from 'react';
import {ArgsTable, Canvas, Meta, Story} from '@storybook/addon-docs';
import {Table} from './Table.tsx';
import {Badge, Button, Image, IconButton} from '../../components';
import {DeleteIcon} from '../../icons';
import {rows, sortRows} from './shared-stories-data';
import {Scrollable} from '../../storybook/PreviewGallery';

<Meta
  title="Components/Table"
  component={Table}
  subcomponents={{
    Table: Table,
    'Table.Header': Table.Header,
    'Table.HeaderCell': Table.HeaderCell,
    'Table.Body': Table.Body,
    'Table.Row': Table.Row,
    'Table.Cell': Table.Cell,
    'Table.ActionCell': Table.ActionCell,
  }}
  argTypes={{
    displayImage: {control: {type: 'boolean'}, description: 'Show or hide the "Image" column'},
    displayRowTitle: {control: {type: 'boolean'}, description: 'Define the "Name" column as row title'},
    isSelectable: {table: {disable: true}},
    displayCheckbox: {table: {disable: true}},
    children: {table: {disable: true}},
  }}
  args={{
    displayRowTitle: false,
    displayImage: true,
  }}
/>

# Table

## Usage

Tables allow users to analyze and manipulate data.

To browse many information at once, for example, view multiple products and their status.
Quickly select and execute bulk actions, such as deleting multiple products, exporting multiple products ...
To compare information, for example how many products are completed versus how many are in progress.

## Basic table

<Canvas>
  <Story name="Standard">
    {args => (
      <Table>
        <Table.Header>
          {args.displayImage && <Table.HeaderCell>Image</Table.HeaderCell>}
          <Table.HeaderCell>Name</Table.HeaderCell>
          <Table.HeaderCell>Family</Table.HeaderCell>
          <Table.HeaderCell>Order</Table.HeaderCell>
          <Table.HeaderCell>Genus</Table.HeaderCell>
          <Table.HeaderCell>Conservation status</Table.HeaderCell>
          <Table.HeaderCell>Actions</Table.HeaderCell>
        </Table.Header>
        <Table.Body>
          <Table.Row>
            {args.displayImage && (
              <Table.Cell>
                <Image src="https://picsum.photos/seed/akeneo/200/140" alt="The alt" />
              </Table.Cell>
            )}
            <Table.Cell rowTitle={args.displayRowTitle}>Giant panda</Table.Cell>
            <Table.Cell>Ursidae</Table.Cell>
            <Table.Cell>Carnivora</Table.Cell>
            <Table.Cell>Ursus</Table.Cell>
            <Table.Cell>
              <Badge level="warning">vu</Badge>
            </Table.Cell>
            <Table.ActionCell>
              <Button level="primary" ghost>
                Button
              </Button>
            </Table.ActionCell>
          </Table.Row>
        </Table.Body>
      </Table>
    )}
  </Story>
</Canvas>

<ArgsTable story="Standard" />

## Sortable header

<Canvas>
  <Story name="Sortable header">
    {args => {
      const [sortedColumn, setSortedColumn] = useState({
        columnName: null,
        sortDirection: null,
      });
      const computeDirection = columnName => {
        if (columnName !== sortedColumn.columnName) {
          return 'none';
        }
        return sortedColumn.sortDirection;
      };
      const handleDirectionChange = columnName => sortDirection => {
        setSortedColumn({
          columnName: columnName,
          sortDirection: sortDirection,
        });
      };
      const sortedRows = sortRows(rows, sortedColumn.columnName, sortedColumn.sortDirection);
      return (
        <Table>
          <Table.Header>
            <Table.HeaderCell>Image</Table.HeaderCell>
            <Table.HeaderCell
              isSortable={true}
              onDirectionChange={handleDirectionChange('name')}
              sortDirection={computeDirection('name')}
            >
              Name
            </Table.HeaderCell>
            <Table.HeaderCell
              isSortable={true}
              onDirectionChange={handleDirectionChange('family')}
              sortDirection={computeDirection('family')}
            >
              Family
            </Table.HeaderCell>
            <Table.HeaderCell>Order</Table.HeaderCell>
            <Table.HeaderCell>Genus</Table.HeaderCell>
            <Table.HeaderCell>Conservation status</Table.HeaderCell>
            <Table.HeaderCell>Actions</Table.HeaderCell>
          </Table.Header>
          <Table.Body>
            {sortedRows.map(row => (
              <Table.Row key={row.name}>
                <Table.Cell>
                  <Image src={row.image} alt="The alt" />
                </Table.Cell>
                <Table.Cell>{row.name}</Table.Cell>
                <Table.Cell>{row.family}</Table.Cell>
                <Table.Cell>{row.order}</Table.Cell>
                <Table.Cell>{row.genus}</Table.Cell>
                <Table.Cell>
                  <Badge level={row.conservation_status_level}>{row.conservation_status}</Badge>
                </Table.Cell>
                <Table.ActionCell>
                  <Button level="primary" onClick={() => {}} ghost>
                    Button
                  </Button>
                </Table.ActionCell>
              </Table.Row>
            ))}
          </Table.Body>
        </Table>
      );
    }}
  </Story>
</Canvas>

## Draggable rows

<Canvas>
  <Story name="Draggable rows">
    {() => {
      const manyRows = [...rows, ...rows, ...rows, ...rows, ...rows, ...rows];
      const [orderedRows, setOrderedRow] = useState(manyRows);
      return (
        <Scrollable height={500}>
          <Table
            isDragAndDroppable={true}
            onReorder={newIndices => {
              setOrderedRow(rows => newIndices.map(index => rows[index]));
            }}
          >
            <Table.Header>
              <Table.HeaderCell>Image</Table.HeaderCell>
              <Table.HeaderCell>Name</Table.HeaderCell>
              <Table.HeaderCell>Family</Table.HeaderCell>
              <Table.HeaderCell>Order</Table.HeaderCell>
              <Table.HeaderCell>Genus</Table.HeaderCell>
              <Table.HeaderCell>Conservation status</Table.HeaderCell>
              <Table.HeaderCell>Actions</Table.HeaderCell>
            </Table.Header>
            <Table.Body>
              {orderedRows.map((row, index) => (
                <Table.Row key={`${row.id}${index}`}>
                  <Table.Cell>
                    <Image src={row.image} alt="The alt" />
                  </Table.Cell>
                  <Table.Cell>
                    {row.name} {index}
                  </Table.Cell>
                  <Table.Cell>{row.family}</Table.Cell>
                  <Table.Cell>{row.order}</Table.Cell>
                  <Table.Cell>{row.genus}</Table.Cell>
                  <Table.Cell>
                    <Badge level={row.conservation_status_level}>{row.conservation_status}</Badge>
                  </Table.Cell>
                  <Table.ActionCell>
                    <Button level="primary" onClick={() => {}} ghost>
                      Button
                    </Button>
                  </Table.ActionCell>
                </Table.Row>
              ))}
            </Table.Body>
          </Table>
        </Scrollable>
      );
    }}
  </Story>
</Canvas>

## Selectable lines

<Canvas>
  <Story name="Selectable lines">
    {args => {
      const [selectedLines, setSelectedLines] = useState([]);
      const handleToggleSelected = lineId => {
        if (selectedLines.indexOf(lineId) === -1) {
          setSelectedLines([...selectedLines, lineId]);
        } else {
          setSelectedLines(selectedLines.filter(currentValue => currentValue !== lineId));
        }
      };
      return (
        <Table isSelectable={true} displayCheckbox={selectedLines.length > 0}>
          <Table.Header>
            <Table.HeaderCell>Image</Table.HeaderCell>
            <Table.HeaderCell>Name</Table.HeaderCell>
            <Table.HeaderCell>Family</Table.HeaderCell>
            <Table.HeaderCell>Order</Table.HeaderCell>
            <Table.HeaderCell>Genus</Table.HeaderCell>
            <Table.HeaderCell>Conservation status</Table.HeaderCell>
            <Table.HeaderCell>Actions</Table.HeaderCell>
          </Table.Header>
          <Table.Body>
            {rows.map(row => (
              <Table.Row
                key={row.id}
                onSelectToggle={() => handleToggleSelected(row.id)}
                isSelected={selectedLines.indexOf(row.id) !== -1}
              >
                <Table.Cell>
                  <Image src={row.image} alt="The alt" />
                </Table.Cell>
                <Table.Cell>{row.name}</Table.Cell>
                <Table.Cell>{row.family}</Table.Cell>
                <Table.Cell>{row.order}</Table.Cell>
                <Table.Cell>{row.genus}</Table.Cell>
                <Table.Cell>
                  <Badge level={row.conservation_status_level}>{row.conservation_status}</Badge>
                </Table.Cell>
                <Table.ActionCell>
                  <Button level="primary" ghost>
                    Button
                  </Button>
                </Table.ActionCell>
              </Table.Row>
            ))}
          </Table.Body>
        </Table>
      );
    }}
  </Story>
</Canvas>

## Clickable lines

<Canvas>
  <Story name="Clickable lines">
    {args => {
      const [data, setData] = useState(
        rows.map(row => {
          return {...row, count: 0};
        })
      );
      const handleClick = rowId => {
        setData(data => {
          return data.map(row => {
            return row.id === rowId ? {...row, count: row.count + 1} : row;
          });
        });
      };
      return (
        <Table>
          <Table.Header>
            <Table.HeaderCell>Image</Table.HeaderCell>
            <Table.HeaderCell>Name</Table.HeaderCell>
            <Table.HeaderCell>Family</Table.HeaderCell>
            <Table.HeaderCell>Order</Table.HeaderCell>
            <Table.HeaderCell>Genus</Table.HeaderCell>
            <Table.HeaderCell>Conservation status</Table.HeaderCell>
            <Table.HeaderCell>Click count</Table.HeaderCell>
            <Table.HeaderCell>Actions</Table.HeaderCell>
          </Table.Header>
          <Table.Body>
            {data.map(row => (
              <Table.Row key={row.id} onClick={() => handleClick(row.id)}>
                <Table.Cell>
                  <Image src={row.image} alt="The alt" />
                </Table.Cell>
                <Table.Cell>{row.name}</Table.Cell>
                <Table.Cell>{row.family}</Table.Cell>
                <Table.Cell>{row.order}</Table.Cell>
                <Table.Cell>{row.genus}</Table.Cell>
                <Table.Cell>
                  <Badge level={row.conservation_status_level}>{row.conservation_status}</Badge>
                </Table.Cell>
                <Table.Cell>{row.count}</Table.Cell>
                <Table.ActionCell>
                  <Button level="primary" ghost>
                    Button
                  </Button>
                </Table.ActionCell>
              </Table.Row>
            ))}
          </Table.Body>
        </Table>
      );
    }}
  </Story>
</Canvas>

## Table with actions
<Canvas>
  <Story name="Table with actions">
    {args => {
      return (
        <Table>
          <Table.Header>
            <Table.HeaderCell>Name</Table.HeaderCell>
            <Table.HeaderCell>Actions</Table.HeaderCell>
          </Table.Header>
          <Table.Body>
            <Table.Row>
              <Table.Cell>A value without actions</Table.Cell>
              <Table.ActionCell />
            </Table.Row>
            <Table.Row>
              <Table.Cell>A value with a button action</Table.Cell>
              <Table.ActionCell>
                <Button level="primary" ghost>
                  A button action
                </Button>
              </Table.ActionCell>
            </Table.Row>
            <Table.Row>
              <Table.Cell>A value with 2 buttons action</Table.Cell>
              <Table.ActionCell>
                <Button level="primary" ghost>
                  A button action
                </Button>
                <Button level="secondary" ghost>
                  A button action
                </Button>
              </Table.ActionCell>
            </Table.Row>
            <Table.Row>
              <Table.Cell>A value with an icon button action</Table.Cell>
              <Table.ActionCell>
                <IconButton level="primary" ghost icon={<DeleteIcon/>}>
                  A button action
                </IconButton>
              </Table.ActionCell>
            </Table.Row>
          </Table.Body>
        </Table>
      );
    }}
  </Story>
</Canvas>

## Complex table

<Canvas>
  <Story name="Complex table">
    {args => {
      const [selectedLines, setSelectedLines] = useState([2, 3]);
      const handleToggleSelected = lineId => {
        if (selectedLines.indexOf(lineId) === -1) {
          setSelectedLines([...selectedLines, lineId]);
        } else {
          setSelectedLines(selectedLines.filter(currentValue => currentValue !== lineId));
        }
      };
      const [data, setData] = useState(
        rows.map(row => {
          return {...row, count: 0};
        })
      );
      const handleClick = rowId => {
        setData(data => data.map(row => (row.id === rowId ? {...row, count: row.count + 1} : row)));
      };
      return (
        <Table isSelectable={true} displayCheckbox={selectedLines.length > 0}>
          <Table.Header>
            <Table.HeaderCell>Image</Table.HeaderCell>
            <Table.HeaderCell>Name</Table.HeaderCell>
            <Table.HeaderCell>Family</Table.HeaderCell>
            <Table.HeaderCell>Order</Table.HeaderCell>
            <Table.HeaderCell>Genus</Table.HeaderCell>
            <Table.HeaderCell>Conservation status</Table.HeaderCell>
            <Table.HeaderCell>Click count</Table.HeaderCell>
            <Table.HeaderCell>Actions</Table.HeaderCell>
          </Table.Header>
          <Table.Body>
            {data.map(row => (
              <Table.Row
                key={row.id}
                onClick={() => handleClick(row.id)}
                onSelectToggle={() => handleToggleSelected(row.id)}
                isSelected={selectedLines.indexOf(row.id) !== -1 ? (row.id == 3 ? 'mixed' : true) : false}
              >
                <Table.Cell>
                  <Image src={row.image} alt="The alt" />
                </Table.Cell>
                <Table.Cell>{row.name}</Table.Cell>
                <Table.Cell>{row.family}</Table.Cell>
                <Table.Cell>{row.order}</Table.Cell>
                <Table.Cell>{row.genus}</Table.Cell>
                <Table.Cell>
                  <Badge level={row.conservation_status_level}>{row.conservation_status}</Badge>
                </Table.Cell>
                <Table.Cell>{row.count}</Table.Cell>
                <Table.ActionCell>
                  <Button level="primary" onClick={() => {}} ghost>
                    Button
                  </Button>
                </Table.ActionCell>
              </Table.Row>
            ))}
          </Table.Body>
        </Table>
      );
    }}
  </Story>
</Canvas>

## Table with sticky header

If you want your `Table.Header` to stay on top when scrolling in the Table, just set the desired `top` position value in the `sticky` prop.

<Canvas>
  <Story name="Sticky header">
    {args => {
      const manyRows = [...rows, ...rows, ...rows, ...rows, ...rows, ...rows];
      return (
        <Scrollable height={250}>
          <Table>
            <Table.Header sticky={0}>
              {args.displayImage && <Table.HeaderCell>Image</Table.HeaderCell>}
              <Table.HeaderCell>Name</Table.HeaderCell>
              <Table.HeaderCell>Family</Table.HeaderCell>
              <Table.HeaderCell>Order</Table.HeaderCell>
              <Table.HeaderCell>Genus</Table.HeaderCell>
              <Table.HeaderCell>Conservation status</Table.HeaderCell>
              <Table.HeaderCell>Actions</Table.HeaderCell>
            </Table.Header>
            <Table.Body>
              {manyRows.map((row, index) => (
                <Table.Row key={`${row.id}${index}`}>
                  <Table.Cell>
                    <Image src={row.image} alt="The alt" />
                  </Table.Cell>
                  <Table.Cell>
                    {row.name} {index}
                  </Table.Cell>
                  <Table.Cell>{row.family}</Table.Cell>
                  <Table.Cell>{row.order}</Table.Cell>
                  <Table.Cell>{row.genus}</Table.Cell>
                  <Table.Cell>
                    <Badge level={row.conservation_status_level}>{row.conservation_status}</Badge>
                  </Table.Cell>
                  <Table.ActionCell>
                    <Button level="primary" ghost>
                      Button
                    </Button>
                  </Table.ActionCell>
                </Table.Row>
              ))}
            </Table.Body>
          </Table>
        </Scrollable>
      );
    }}
  </Story>
</Canvas>

## Table with warning and locked rows

<Canvas>
    <Story name="Warning and locked rows">
        {args => {
            return (
                <Scrollable height={250}>
                    <Table hasWarningRows={true} hasLockedRows={true}>
                        <Table.Header sticky={0}>
                            <Table.HeaderCell>Name</Table.HeaderCell>
                            <Table.HeaderCell>Family</Table.HeaderCell>
                            <Table.HeaderCell>Order</Table.HeaderCell>
                            <Table.HeaderCell>Genus</Table.HeaderCell>
                            <Table.HeaderCell>Conservation status</Table.HeaderCell>
                            <Table.HeaderCell>Actions</Table.HeaderCell>
                        </Table.Header>
                        <Table.Body>
                            <Table.Row level="tertiary">
                                <Table.Cell rowTitle={args.displayRowTitle}>Giant panda</Table.Cell>
                                <Table.Cell>Ursidae</Table.Cell>
                                <Table.Cell>Carnivora</Table.Cell>
                                <Table.Cell>Ursus</Table.Cell>
                                <Table.Cell>
                                    <Badge level="warning">vu</Badge>
                                </Table.Cell>
                                <Table.ActionCell>
                                    <Button level="primary" ghost>
                                        Button
                                    </Button>
                                </Table.ActionCell>
                            </Table.Row>
                            <Table.Row level="warning">
                                <Table.Cell rowTitle={args.displayRowTitle}>Giant panda</Table.Cell>
                                <Table.Cell>Ursidae</Table.Cell>
                                <Table.Cell>Carnivora</Table.Cell>
                                <Table.Cell>Ursus</Table.Cell>
                                <Table.Cell>
                                    <Badge level="warning">vu</Badge>
                                </Table.Cell>
                                <Table.ActionCell>
                                    <Button level="primary" ghost>
                                        Button
                                    </Button>
                                </Table.ActionCell>
                            </Table.Row>
                            <Table.Row>
                                <Table.Cell rowTitle={args.displayRowTitle}>Red panda</Table.Cell>
                                <Table.Cell>Ailuridae</Table.Cell>
                                <Table.Cell>Carnivora</Table.Cell>
                                <Table.Cell>Ailurus</Table.Cell>
                                <Table.Cell>
                                    <Badge level="warning">vu</Badge>
                                </Table.Cell>
                                <Table.ActionCell>
                                    <Button level="primary" ghost>
                                        Button
                                    </Button>
                                </Table.ActionCell>
                            </Table.Row>
                        </Table.Body>
                    </Table>
                </Scrollable>
            );
        }}
    </Story>
</Canvas>

## Table with multiple actions

<Canvas>
    <Story name="Multiple actions">
        {args => {
            return (
                <Scrollable height={250}>
                    <Table hasWarningRows={true}>
                        <Table.Header sticky={0}>
                            <Table.HeaderCell>Name</Table.HeaderCell>
                            <Table.HeaderCell>Family</Table.HeaderCell>
                            <Table.HeaderCell>Order</Table.HeaderCell>
                            <Table.HeaderCell>Genus</Table.HeaderCell>
                            <Table.HeaderCell>Conservation status</Table.HeaderCell>
                            <Table.HeaderCell>Actions</Table.HeaderCell>
                        </Table.Header>
                        <Table.Body>
                            <Table.Row level="warning">
                                <Table.Cell rowTitle={args.displayRowTitle}>Giant panda</Table.Cell>
                                <Table.Cell>Ursidae</Table.Cell>
                                <Table.Cell>Carnivora</Table.Cell>
                                <Table.Cell>Ursus</Table.Cell>
                                <Table.Cell>
                                    <Badge level="warning">vu</Badge>
                                </Table.Cell>
                                <Table.ActionCell>
                                    <Button level="primary" ghost>
                                        View
                                    </Button>
                                    <Button level="danger" ghost>
                                        Delete
                                    </Button>
                                </Table.ActionCell>
                            </Table.Row>
                            <Table.Row>
                                <Table.Cell rowTitle={args.displayRowTitle}>Red panda</Table.Cell>
                                <Table.Cell>Ailuridae</Table.Cell>
                                <Table.Cell>Carnivora</Table.Cell>
                                <Table.Cell>Ailurus</Table.Cell>
                                <Table.Cell>
                                    <Badge level="warning">vu</Badge>
                                </Table.Cell>
                                <Table.ActionCell>
                                    <Button level="primary" ghost>
                                        View
                                    </Button>
                                    <Button level="danger" ghost>
                                        Delete
                                    </Button>
                                </Table.ActionCell>
                            </Table.Row>
                        </Table.Body>
                    </Table>
                </Scrollable>
            );
        }}
    </Story>
</Canvas>
